package com.thirtydays.frame.ui.webview

import android.content.Context
import android.graphics.drawable.BitmapDrawable
import android.net.http.SslError
import android.util.AttributeSet
import android.view.View
import android.webkit.*
import coil.ImageLoader
import coil.imageLoader
import coil.request.ImageRequest
import com.blankj.utilcode.util.ActivityUtils
import com.blankj.utilcode.util.LogUtils
import com.thirtydays.frame.app.MyApp
import com.thirtydays.frame.base.BaseApp
import com.thirtydays.frame.util.XpopHelp
import com.thirtydays.frame.util.ext.saveBitMap
import com.thirtydays.frame.util.ext.toNullString
import java.io.File

/**
 * @author 小垚
 * @创建时间： 2020/11/23
 * @描述： 统一配置webview
 **/
class MyWebView : WebView {

    constructor(context: Context) : super(context) {
        initView(context)
    }

    constructor(context: Context, attrs: AttributeSet?) : super(context, attrs) {
        initView(context)
    }

    constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(context, attrs, defStyleAttr) {
        initView(context)
    }

    private val cachePath by lazy { BaseApp.appContent.cacheDir.absolutePath + "/webview" }
    private fun initView(context: Context) {
        // 默认支持嵌套滑动
        overScrollMode = View.OVER_SCROLL_NEVER
        isNestedScrollingEnabled = false

        isVerticalScrollBarEnabled = false

        settings.apply {
            // 是否使用内置的缩放控件
            builtInZoomControls = true

            // 是否保存密码
            savePassword = false
            saveFormData = false
            // 设置缓存模式
            cacheMode = WebSettings.LOAD_DEFAULT
            javaScriptEnabled = true
            // 设置自适应屏幕，两者合用
            useWideViewPort = true
            loadWithOverviewMode = true
            // 是否显示原生的缩放控件
            displayZoomControls = false
            // 是否可以访问文件
            allowFileAccess = true
            // 配置当安全源试图从不安全源加载资源时WebView的行为
            mixedContentMode = WebSettings.MIXED_CONTENT_ALWAYS_ALLOW
            //是否支持通过js打开新窗口
            javaScriptCanOpenWindowsAutomatically = true
            // 是否启用 DOM storage API
            domStorageEnabled = true
            // 是否启用 database storage API 功能
            databaseEnabled = true
            // 是否支持自动加载图片
            loadsImagesAutomatically = true
            blockNetworkImage = false
            //设置编码格式
            defaultTextEncodingName = "UTF-8"
            layoutAlgorithm = WebSettings.LayoutAlgorithm.NORMAL
            // 是否支持缩放，默认为true
            setSupportZoom(false)
        }

        initListener()
    }

    private fun initListener() {
        webViewClient = object : WebViewClient() {
            override fun shouldOverrideUrlLoading(view: WebView?, url: String?): Boolean {
                view?.loadUrl(url!!)
                return true
            }

            override fun shouldOverrideUrlLoading(view: WebView?, request: WebResourceRequest?): Boolean {
                request?.let {
                    it.url?.let { urls ->
                        view?.loadUrl(urls.toString())
                    }
                }
                return true
            }

            //ssl证书过期
            override fun onReceivedSslError(view: WebView?, handler: SslErrorHandler, error: SslError?) {
                XpopHelp.showCenterTip(ActivityUtils.getTopActivity(), "当前网站安全证书已过期或不可信\n是否继续浏览?", onCancel = {
                    handler.cancel()
                }) {
                    it.dismiss()
                    handler.proceed()
                }
            }

            override fun shouldInterceptRequest(view: WebView, request: WebResourceRequest): WebResourceResponse? {
                var webResourceResponse: WebResourceResponse? = null

                // 如果是 assets 目录下的文件
                if (isAssetsResource(request)) {
                    webResourceResponse = assetsResourceRequest(view.context, request)
                }


                if (webResourceResponse == null) {
                    webResourceResponse = super.shouldInterceptRequest(view, request)
                }
                return webResourceResponse
            }
        }

        webChromeClient = object : WebChromeClient() {
            override fun onConsoleMessage(consoleMessage: ConsoleMessage?): Boolean {
                LogUtils.e("webview:${consoleMessage?.message()}")
                return super.onConsoleMessage(consoleMessage)
            }

            override fun onJsAlert(view: WebView?, url: String?, message: String?, result: JsResult?): Boolean {
                XpopHelp.showCenterTip(ActivityUtils.getTopActivity(), message.toNullString()) {
                    it.dismiss()
                }
                return true
            }

            override fun onJsConfirm(view: WebView?, url: String?, message: String?, result: JsResult?): Boolean {
                XpopHelp.showCenterTip(ActivityUtils.getTopActivity(), message.toNullString()) {
                    it.dismiss()
                }
                return true
            }
        }
    }

    private fun isAssetsResource(webRequest: WebResourceRequest): Boolean {
        val url = webRequest.url.toString()
        return url.startsWith("file:///android_asset/")
    }

    /**
     * assets 文件请求
     */
    private fun assetsResourceRequest(
        context: Context,
        webRequest: WebResourceRequest
    ): WebResourceResponse? {
        val url = webRequest.url.toString()
        try {
            val filenameIndex = url.lastIndexOf("/") + 1
            val filename = url.substring(filenameIndex)
            val suffixIndex = url.lastIndexOf(".")
            val suffix = url.substring(suffixIndex + 1)
            val webResourceResponse = WebResourceResponse(
                getMimeTypeFromUrl(url),
                "UTF-8",
                context.assets.open("$suffix/$filename")
            )
            webResourceResponse.responseHeaders = mapOf("access-control-allow-origin" to "*")
            return webResourceResponse
        } catch (e: Exception) {
            e.printStackTrace()
        }
        return null
    }

    /**
     * 判断是否是可以被缓存等资源
     */
    private fun isCacheResource(webRequest: WebResourceRequest): Boolean {
        val url = webRequest.url.toString()
        val extension = MimeTypeMap.getFileExtensionFromUrl(url)
        return extension == "ico" || extension == "bmp" || extension == "gif"
                || extension == "jpeg" || extension == "jpg" || extension == "png"
                || extension == "svg" || extension == "webp" || extension == "css"
                || extension == "js" || extension == "json" || extension == "eot"
                || extension == "otf" || extension == "ttf" || extension == "woff"
    }

    /**
     * 判断是否是图片
     * 有些文件存储没有后缀，也可以根据自家服务器域名等等
     */
    private fun isImageResource(webRequest: WebResourceRequest): Boolean {
        val url = webRequest.url.toString()
        val extension = MimeTypeMap.getFileExtensionFromUrl(url)
        return extension == "ico" || extension == "bmp" || extension == "gif"
                || extension == "jpeg" || extension == "jpg" || extension == "png"
                || extension == "svg" || extension == "webp"
    }

    /**
     * 根据 url 获取文件类型
     */
    private fun getMimeTypeFromUrl(url: String): String {
        try {
            val extension = MimeTypeMap.getFileExtensionFromUrl(url)
            if (extension.isNotBlank() && extension != "null") {
                if (extension == "json") {
                    return "application/json"
                }
                return MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension) ?: "*/*"
            }
        } catch (e: Exception) {
            e.printStackTrace()
        }
        return "*/*"
    }

}